package homework.yuandan.common.aspect;

import com.alibaba.druid.util.StringUtils;
import homework.yuandan.beans.dto.UserDTO;
import homework.yuandan.common.ResponseEnum;
import homework.yuandan.common.annotation.AuthRight;
import homework.yuandan.config.TokenContainer;
import homework.yuandan.exception.AppException;
import homework.yuandan.service.RoleService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 作者:49293
 * 时间:2021/1/6-14:59
 * @author 49293
 */
@Component
@Aspect
public class RightAspect {
    @Resource
    TokenContainer tokenContainer;
    @Resource
    RoleService roleService;
    @Around("@annotation(homework.yuandan.common.annotation.AuthRight)")
    public Object checkRight(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("进来了");
        //1 获得token
        // 获得此此请求
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert servletRequestAttributes != null;
        HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
        // 获取头部token
        String token = httpServletRequest.getHeader("X-Token");
        System.out.println("token为:"+token);

        //2 验证token
        // 2.1  没有token
        if(StringUtils.isEmpty(token)){
            throw new AppException(ResponseEnum.TOKEN_ERROR);
        }
        // 2.2  错误token
        // 2.3  token超时
        UserDTO userDTO = tokenContainer.parserJavaWebToken(token);
        System.out.println("用户名为:"+userDTO.getNickName());
        //3 从token中获得roleId
        Integer roleId = userDTO.getRoleId();
        //4 根据角色id获得该角色拥有的权限码的集合
        List<String> stringList = roleService.selectRightCodeByRoleId(roleId);
        //5 通过反射获得进入的方法所需要的权限
        MethodSignature methodSignature = (MethodSignature) jp.getSignature();
        Method method = methodSignature.getMethod();
        AuthRight annotation = method.getAnnotation(AuthRight.class);
        // 要执行这个方法所拥有的权限码
        String rightCode = annotation.rightCode();
        //6判断当前角色的权限码的集合当中是否具备权限吗
        if (!stringList.contains(rightCode)) {
            throw new AppException(ResponseEnum.ROLE_NO_RIGHT);
        }
        //  6.1放行
        return jp.proceed();
    }
}
